#ifndef _AI_ARMY_DATA_CACHE_INC
#define _AI_ARMY_DATA_CACHE_INC

// Created to de-couple the build dependence between creature_array.h and ai specific data.
// Also, to allow the ai to hold a reference to the current cache and work on it directly.

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "adv_map_point.h"
#include "counted_ptr.h"

#include <limits>

class t_town;

class t_ai_army_data_cache : public t_counted_object
{
public:
	typedef std::list< t_town* > t_threat_list;
	
	t_ai_army_data_cache();

	void					increment_bounty( float value );
	bool					is_sleeping() const;
	bool					is_targeting() const;
	void					clear_target();
	void					compare_nearest_town( t_town* town, int distance );
	float					get_bounty() const;
	t_town*					get_nearest_town() const;
	int						get_nearest_town_distance() const;
	bool					get_new_army() const;
	t_adv_map_point const&	get_target() const;
	int						get_target_distance() const;
	float					get_target_value() const;
	t_threat_list const&	get_threat_list() const;
	bool					get_urgent_target() const;
	bool					has_moved_once() const;
	void					inc_threat( t_town* town );
	void					set_new_army( bool new_army = true );
	void					set_moved_once( bool moved_once );
	void					set_sleeping( bool sleeping );
	void					set_target( t_adv_map_point const& point, float value, int distance );
	void					set_urgent_target( bool urgent );
	void					start_turn();

protected:
	float					m_bounty;
	bool					m_is_sleeping;
	bool					m_has_target;
	bool					m_moved_once;
	t_town*					m_nearest_town;
	int						m_nearest_town_distance;
	bool					m_new_army;
	t_adv_map_point			m_target;
	int						m_target_distance;
	float					m_target_value;
	t_threat_list			m_threat_list;
	bool					m_urgent_target;
};

inline t_ai_army_data_cache::t_ai_army_data_cache()
	: m_is_sleeping(false), m_has_target(false), m_moved_once(false), 
		m_target_distance(-1), m_new_army(false), m_urgent_target(false),
		m_nearest_town( NULL ), m_nearest_town_distance(-1),
		m_bounty(0.0f)
{
}

inline void t_ai_army_data_cache::compare_nearest_town( t_town* town, int distance )
{
	if (distance < m_nearest_town_distance)
	{
		m_nearest_town_distance = distance;
		m_nearest_town = town;
	}
}

inline t_town* t_ai_army_data_cache::get_nearest_town() const
{
	return m_nearest_town;
}

inline int t_ai_army_data_cache::get_nearest_town_distance() const
{
	return m_nearest_town_distance;
}

inline void t_ai_army_data_cache::inc_threat( t_town* town )
{
	m_threat_list.push_back( town );
}

inline t_ai_army_data_cache::t_threat_list const& t_ai_army_data_cache::get_threat_list() const
{
	return m_threat_list;
}

inline void t_ai_army_data_cache::start_turn()
{
	m_moved_once = false;
	m_is_sleeping = false;
	m_has_target = false;
	m_target_distance = -1;
	m_target_value = 0.0f;
	m_threat_list.clear();
	m_new_army = false;
	m_urgent_target = false;
	m_nearest_town = NULL;
	m_nearest_town_distance = std::numeric_limits<int>::max();
	m_bounty = 0.0f;
}

inline void t_ai_army_data_cache::increment_bounty( float value )
{
	m_bounty += value;
}

inline float t_ai_army_data_cache::get_bounty() const
{
	return m_bounty;
}

inline void	t_ai_army_data_cache::set_new_army( bool new_army )
{
	m_new_army = new_army;
}

inline void t_ai_army_data_cache::set_urgent_target( bool urgent )
{
	m_urgent_target = urgent;
}

inline bool	t_ai_army_data_cache::get_new_army() const
{
	return m_new_army;
}

inline bool t_ai_army_data_cache::get_urgent_target() const
{
	return m_urgent_target;
}

inline void t_ai_army_data_cache::clear_target() 
{
	m_has_target = false;
}

inline bool t_ai_army_data_cache::is_sleeping() const
{
	return m_is_sleeping;
}

inline bool t_ai_army_data_cache::is_targeting() const
{
	return m_has_target;
}

inline t_adv_map_point const& t_ai_army_data_cache::get_target() const
{
	return m_target;
}

inline int t_ai_army_data_cache::get_target_distance() const
{
	return m_target_distance;
}

inline float t_ai_army_data_cache::get_target_value() const
{
	return m_target_value;
}

inline bool t_ai_army_data_cache::has_moved_once() const
{
	return m_moved_once;
}

inline void t_ai_army_data_cache::set_moved_once( bool moved_once )
{
	m_moved_once = moved_once;
}

inline void t_ai_army_data_cache::set_target( t_adv_map_point const& point, float value, int distance )
{
	m_has_target = true;
	m_target = point;
	m_target_distance = distance;
	m_target_value = value;
}

inline void t_ai_army_data_cache::set_sleeping( bool sleeping )
{
	m_is_sleeping = sleeping;
}

#endif
